package com.kaia.shoebox.activity;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ListView;
import android.widget.Toast;

import com.j256.ormlite.android.apptools.OpenHelperManager;
import com.j256.ormlite.dao.RuntimeExceptionDao;
import com.kaia.shoebox.R;
import com.kaia.shoebox.adapter.TodoListAdapter;
import com.kaia.shoebox.adapter.TodoListAdapter.ViewHolder;
import com.kaia.shoebox.animation.ExpandCollapseAnimation;
import com.kaia.shoebox.db.DbHelper;
import com.kaia.shoebox.db.dao.Importance;
import com.kaia.shoebox.db.dao.TodoItem;

public class ShoeboxActivity extends ListActivity {

	// ------------------------------------------------------------------
	// Constants
	// ------------------------------------------------------------------

	private static final String TAG = ShoeboxActivity.class.getSimpleName();

	public static final int NEW_TODO_INTENT = 0;

	protected static final int DROP_TIME = 1000;

	// ------------------------------------------------------------------
	// Attributes
	// ------------------------------------------------------------------

	private DbHelper mHelper;

	private TodoListAdapter mAdapter;

	// ------------------------------------------------------------------
	// System Methods
	// ------------------------------------------------------------------

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		new LoadList().execute();

		ListView list = getListView();

		list.setTextFilterEnabled(true);
		registerForContextMenu(list);
	}

	@Override
	protected void onResume() {
		super.onResume();
		if (mAdapter != null) {
			Log.i(TAG, "refreshing list");
			mAdapter.notifyDataSetChanged();
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();

		Log.i(TAG, "Releasing Database Instance");
		if (mHelper != null) {
			OpenHelperManager.releaseHelper();
			mHelper = null;
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch (requestCode) {
		case NEW_TODO_INTENT:
			if (resultCode == RESULT_OK) {
				String title = data.getStringExtra("title");
				long due = data.getLongExtra("due", 0);
				String notes = data.getStringExtra("notes");
				int imp = data.getIntExtra("importance", 0);

				Date dueDate = new Date(due);
				Importance importance = Importance.getImprtanceByNumber(imp);

				addNewTodo(new TodoItem(title, dueDate, notes, importance));
			}
			break;

		default:
			break;
		}
	}

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		// TODO
		// ViewHolder holder = (ViewHolder) v.getTag();
		// final View dropdown = holder.getDropDown();
		//
		// final View simpleView = v
		// .findViewById(R.id.item_simple_parent_invis_cover);
		// simpleView.setVisibility(View.VISIBLE);
		//
		// final Handler handler = new Handler() {
		//
		// @Override
		// public void handleMessage(Message msg) {
		// if (msg.what == 0) {
		// ExpandCollapseAnimation.setHeightForWrapContent(
		// ShoeboxActivity.this, dropdown);
		// ExpandCollapseAnimation animation = new ExpandCollapseAnimation(
		// dropdown, DROP_TIME);
		// dropdown.startAnimation(animation);
		//
		// Message newMsg = new Message();
		//
		// } else if (msg.what == 1) {
		// ExpandCollapseAnimation animation = new ExpandCollapseAnimation(
		// dropdown, DROP_TIME);
		// dropdown.startAnimation(animation);
		// simpleView.setOnClickListener(null);
		// simpleView.setVisibility(View.GONE);
		// }
		// }
		//
		// };
		//
		// simpleView.setOnClickListener(new View.OnClickListener() {
		//
		// public void onClick(View v) {
		// handler.sendEmptyMessage(1);
		// }
		// });
		//
		// handler.sendEmptyMessage(0);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.main_options_menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_add_new_todo:
			Intent intent = new Intent(ShoeboxActivity.this,
					NewTodoActivity.class);
			startActivityForResult(intent, NEW_TODO_INTENT);
			break;
		case R.id.menu_search:
			InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
			imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
			break;
		case R.id.sort_due_date:
			Log.i(TAG, "Sorting list by due date");
			mAdapter.sortByDueDate();
			break;
		case R.id.sort_importance:
			Log.i(TAG, "Sorting list by importance");
			mAdapter.sortByImportance();
			break;
		case R.id.sort_created_date:
			Log.i(TAG, "Sorting list by created date");
			mAdapter.sortBycreatedDate();
			break;
		}

		return true;
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.item_context_menu, menu);
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
				.getMenuInfo();
		switch (item.getItemId()) {
		case R.id.item_delete:
			deleteTodo((int) info.id);
			return true;
		case R.id.item_edit:
			return true;
		case R.id.item_done:
			return true;
		default:
			return super.onContextItemSelected(item);
		}

	}

	// ------------------------------------------------------------------
	// Utility Methods
	// ------------------------------------------------------------------

	private DbHelper getHelper() {

		Log.i(TAG, "Requesting Database Instance");
		if (mHelper == null) {
			mHelper = (DbHelper) OpenHelperManager.getHelper(this,
					DbHelper.class);
		}

		return mHelper;
	}

	private void deleteTodo(int itemPos) {

		final TodoItem item = mAdapter.getItem(itemPos);

		Log.i(TAG, "Deleting item: " + item.getId());

		final RuntimeExceptionDao<TodoItem, Integer> todoDao = getHelper()
				.getRuntimeDao();

		final Animation animation = AnimationUtils.loadAnimation(this,
				R.anim.fade_out);
		View rowView = getListView().getChildAt(itemPos);
		rowView.startAnimation(animation);

		Handler handler = new Handler();
		handler.postDelayed(new Runnable() {

			public void run() {
				if (todoDao.delete(item) == 1) {
					mAdapter.deleteListItem(item);
					Toast.makeText(ShoeboxActivity.this,
							"Successfully deleted item", Toast.LENGTH_SHORT)
							.show();
				} else {
					Log.e(TAG, "Couldn't delete item from database");
					Toast.makeText(ShoeboxActivity.this,
							"Couldn't delete item", Toast.LENGTH_SHORT).show();
				}
			}
		}, 1000);

	}

	private void addNewTodo(TodoItem item) {

		RuntimeExceptionDao<TodoItem, Integer> todoDao = getHelper()
				.getRuntimeDao();
		
		if (todoDao.create(item) == 1) {
			mAdapter.addListItem(item);
		} else {
			Log.e(TAG, "couldn't add element to database");
			Toast.makeText(this, "Error adding item", Toast.LENGTH_LONG).show();
		}
	}

	// ------------------------------------------------------------------
	// AsyncTask
	// ------------------------------------------------------------------

	private class LoadList extends AsyncTask<Void, Void, List<TodoItem>> {

		@Override
		protected List<TodoItem> doInBackground(Void... params) {
			try {
				RuntimeExceptionDao<TodoItem, Integer> todoDao = getHelper()
						.getRuntimeDao();

				List<TodoItem> listItems = todoDao.query(todoDao.queryBuilder()
						.where().ne(TodoItem.IMPORTANCE, Importance.DONE)
						.prepare());
				Log.i(TAG, "Found " + listItems.size()
						+ " entries for the list");

				return listItems;
			} catch (SQLException e) {
				Log.e(TAG, "Error while querying the database", e);
				Toast.makeText(ShoeboxActivity.this,
						"There was an error while populating the list",
						Toast.LENGTH_LONG).show();
			}
			return new ArrayList<TodoItem>();
		}

		@Override
		protected void onPostExecute(List<TodoItem> result) {
			mAdapter = new TodoListAdapter(ShoeboxActivity.this, result);

			setListAdapter(mAdapter);
		}
	}
}